package com.sonymobile.uiautotestutils;
/**
 * @author Qi Huaping
 * @version v1.2
 */
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import junit.framework.Assert;

import android.app.Instrumentation;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import com.android.uiautomator.core.UiCollection;
import com.android.uiautomator.core.UiDevice;
import com.android.uiautomator.core.UiObject;
import com.android.uiautomator.core.UiObjectNotFoundException;
import com.android.uiautomator.core.UiScrollable;
import com.android.uiautomator.core.UiSelector;
import com.android.uiautomator.core.UiWatcher;
/**
 * @version 0.1
 * @author Qi Huaping
 */
import com.android.uiautomator.testrunner.UiAutomatorTestCase;


public class ATCUiAutoTestCase extends UiAutomatorTestCase {
	public long TIMEOUT= Constant.TIMEOUT;
	private String AUTOTEST_TAG = Constant.LOG_TAG;
	Instrumentation inst;
		  
	public ATCUiAutoTestCase(){
	}
	public ATCUiAutoTestCase(String appName) {
	}

	public ATCUiAutoTestCase(int timeout) {
	}

	public ATCUiAutoTestCase(int timeout, String tagName) {
		this.AUTOTEST_TAG = tagName;
	}

	/**
	 * This method is to click Class name on screen by instance
	 *
	 * @param cls
	 *            cls: you can get from uiautomatorviewer "class" name in Node
	 *            details
	 *
	 * @param instance Set the search criteria to match the widget by its instance number. 
	 * The instance value must be 0 or greater, where the first instance is 0. For example, 
	 * to simulate a user click on the third image that is enabled in a UI screen, 
	 * you could specify a a search criteria where the instance is 2
	 *
	 *@param isNewWindow It will wait for new window open
	 *
	 * @throws UiObjectNotFoundException
	 *             if the class not found
	 */
	public void clickClass(String cls, int instance, boolean isNewWindow)
			throws UiObjectNotFoundException {
		UiObject obj = new UiScrollable(new UiSelector().className(cls)
				.instance(instance));
		if (!isNewWindow)
			obj.click();
		else
			obj.clickAndWaitForNewWindow(TIMEOUT);
	}


	/**
	 * This method is to click Text label on screen
	 *
	 * @param text
	 *            text: you can get from uiautomatorviewer "text" name in Node
	 *            details
	 * @param isNewWindow wait new window open after clicking
	 *
	 * @throws UiObjectNotFoundException
	 *             if the class not found
	 */
	public void clickText(String text, boolean isNewWindow) throws UiObjectNotFoundException {
		UiObject obj = new UiObject(new UiSelector().text(text));
		if (!isNewWindow)
			obj.click();
		else
			obj.clickAndWaitForNewWindow(TIMEOUT);
	}

	/**
	 * This method is to click label contains some strings on screen
	 *
	 * @param text
	 *            text: you can get from uiautomatorviewer "text" name in Node
	 *            details *
	 *
	 * @param isNewWindow wait new window open after clicking
	 *
	 * @throws UiObjectNotFoundException
	 *             if the class not found
	 */
	public void clickTextContains(String text, boolean isNewWindow) throws UiObjectNotFoundException {
		UiObject obj = new UiObject(new UiSelector().textContains(text));
		if (!isNewWindow)
			obj.click();
		else
			obj.clickAndWaitForNewWindow(TIMEOUT);
	}

	/**
	 * This method is to click label contains some Regular Express strings on
	 * screen
	 *
	 * @param regExp
	 *            regExp: you can get from uiautomatorviewer "text" name in Node
	 *            details *
	 *
	 * @param isNewWindow wait for new window after click
	 *
	 * @throws UiObjectNotFoundException
	 *             if the class not found
	 */
	public void clickTextRegExp(String regExp, boolean isNewWindow) throws UiObjectNotFoundException {
		UiObject obj = new UiObject(new UiSelector().textMatches(regExp));
		if (!isNewWindow)
			obj.click();
		else
			obj.clickAndWaitForNewWindow(TIMEOUT);
	}

	/**
	 * This method is to click content description contains some text strings on
	 * screen
	 *
	 * @param text
	 *            text: you can get from uiautomatorviewer "content-desc" name
	 *            in Node details *
	 *
	 * @param isNewWindow wait for new window after click
	 *
	 * @throws UiObjectNotFoundException
	 *             if the class not found
	 */
	public void clickContentDescContains(String text, boolean isNewWindow)
			throws UiObjectNotFoundException {
		UiObject obj = new UiObject(
				new UiSelector().descriptionContains(text));
		if (!isNewWindow)
			obj.click();
		else
			obj.clickAndWaitForNewWindow(TIMEOUT);
	}

	/**
	 * This method is to click content description strings on screen
	 *
	 * @param text
	 *            text: you can get from uiautomatorviewer "content-desc" name
	 *            in Node details *
	 *
	 * @param isNewWindow wait for new window after click
	 *
	 * @throws UiObjectNotFoundException
	 *             if the class not found
	 */
	public void clickContentDesc(String text, boolean isNewWindow) throws UiObjectNotFoundException {
		UiObject obj = new UiObject(new UiSelector().description(text));
		if (!isNewWindow)
			obj.click();
		else
			obj.clickAndWaitForNewWindow(TIMEOUT);
	}

	
	/**
	 * This method is to click child Class View strings on screen
	 * @param className
	 * @param instance
	 * @param isNewWindow
	 * @throws UiObjectNotFoundException
	 */
	public void clickChildItemByInstance(String className, int instance, boolean isNewWindow) throws UiObjectNotFoundException {
		UiCollection uiCol = new UiCollection(new UiSelector());
		UiObject obj = uiCol.getChildByInstance(new UiSelector().className(className), instance);
		if(!isNewWindow)
			obj.click();
		else 
			obj.clickAndWaitForNewWindow(TIMEOUT);
	}

	/**
	 * This method is to click child Class View is strings on screen, this use for many same text
	 *
	 * @param cls
	 *             you can get from uiautomatorviewer "cls" name in Node
	 *            details *
	 *            
	 * @param text
	 *            the child text you look for.
	 * @throws UiObjectNotFoundException
	 *             if the class not found
	 */
	//test ok
	public void clickChildByText(String cls, String text, boolean isNewWindow)
			throws UiObjectNotFoundException {
		UiCollection uiColl = new UiCollection(new UiSelector());
		UiObject obj = uiColl.getChildByText(new UiSelector().className(cls),
				text);
		if (!isNewWindow) {
			obj.click();
		} else {
			obj.clickAndWaitForNewWindow(TIMEOUT);
		}
	}

	/**
	 * Performs a swipe from one coordinate to another using the number of steps
	 * to determine smoothness and speed. Each step execution is throttled to
	 * 5ms per step. So for a 100 steps, the swipe will take about 1/2 second to
	 * complete.
	 *
	 * @param steps
	 *            is the number of move steps sent to the system
	 */
	//test ok
	public void drag(int startX, int startY, int endX, int endY, int steps) {
		getUiDevice().swipe(startX, startY, endX, endY, steps);
	}
	
	public void dragRelative(float startX, float startY, float endX, float endY, int steps){
		drag(toScreenX(startX), toScreenY(startY), toScreenX(endX), toScreenY(endY), steps);
	}

	/**
	 * Performs a swipe from one coordinate to another using the number of steps
	 * to determine smoothness and speed.
	 *
	 * @param segmentSteps
	 *            is the number of move steps sent to the system, Each step
	 *            execution is throttled to 5ms per step. So for a 100 steps,
	 *            the swipe will take about 1/2 second to complete.
	 */
	public void drag(Point[] segments, int segmentSteps) {
		getUiDevice().swipe(segments, segmentSteps);

	}

	/**
	 * Drag screen by direction, left, right, up, or down
	 *
	 * @param direction
	 *            steps
	 * @param steps
	 *            Speed: 1=2ms, 100=1/2 seconds, normally=20
	 */
	//test ok
	public void dragDirection(String direction, int steps) {
		int startX = toScreenX(0.25f);
		int endX = toScreenX(0.75f);
		int startY = toScreenY(0.25f);
		int endY = toScreenY(0.75f);
		int H = getUiDevice().getDisplayHeight(); // y
		int W = getUiDevice().getDisplayWidth(); // x
		if (direction.equalsIgnoreCase("left")) {
			drag(endX, H / 2, startX, H / 2, steps);
		} else if (direction.equalsIgnoreCase("right")) {
			drag(startX, H / 2, endX, H / 2, steps);
		} else if (direction.equalsIgnoreCase("up")) {
			drag(W / 2, endY, W / 2, startY, steps);
		} else if (direction.equalsIgnoreCase("down")) {
			drag(W / 2, startY, W / 2, endY, steps);
		} else {
			drag(endX, H / 2, startX, H / 2, steps);
		}
	}

	/**
	 * get center coordinate of a text view label
	 */
	public Point getCoordinateByView(String cls, int instance)
			throws UiObjectNotFoundException {
		UiObject obj = new UiObject(new UiSelector().className(cls)
				.instance(instance));
		Point pt = new Point();
		pt.x = obj.getBounds().centerX();
		pt.y = obj.getBounds().centerY();
		return pt;
	}

	/**
	 * drag from text to text (from coordinate)
	 * @param from  text you drag start from
	 * @param end	text you drag stop
	 * @param steps	speed of drag, 100 is 1/2 seconds, normally, 15~20
	 * @throws UiObjectNotFoundException
	 */
	public void drag(String from, String end, int steps)
			throws UiObjectNotFoundException {
		Point[] segments = { getCoordinateByText(from),
				getCoordinateByText(end) };
		drag(segments, steps);
	}

	/**
	 * drag from view to view by Class name
	 * @param clsFrom drag start from class name
	 * @param instanceFrom drag start from class instance
	 * @param clsTo drag end of class name
	 * @param instanceTo drag end of class indoex
	 * @param segmentSteps speed of drag motions, 100 is 0.5s, normally ~20
	 * @throws UiObjectNotFoundException
	 */
	public void dragViewByClsToView(String clsFrom, int instanceFrom,
			String clsTo, int instanceTo, int segmentSteps)
			throws UiObjectNotFoundException {
		Point[] segments = { getCoordinateByView(clsFrom, instanceFrom),
				getCoordinateByView(clsTo, instanceTo) };
		drag(segments, segmentSteps);
	}

	/**
	 * unlock screen, also used from wakeup screen
	 */
	//test ok
	public void disableLockScreen() throws RemoteException {
		if (!getUiDevice().isScreenOn()) {
			getUiDevice().wakeUp();
			drag(toScreenX(0.5f), toScreenY(0.8f), toScreenX(0.5f),
					toScreenY(0.3f), 14);
			pressKey("Home");
			pressKey("Home");
		} else {
			
			UiObject obj = new UiObject(new UiSelector().className("android.appwidget.AppWidgetHostView"));
			UiObject obj1 = new UiObject(new UiSelector().className("Swipe up or down to unlock"));
			if (obj.exists() || obj1.exists()){
				drag(toScreenX(0.5f), toScreenY(0.6f), toScreenX(0.5f),
						toScreenY(0.2f), 30);
				pressKey("Home");
				pressKey("Home");				
			}
		}
	}

	/**
	 * wake up screen, also used from wakeup screen
	 */
	public void wakeUp() throws RemoteException {
		if (!getUiDevice().isScreenOn()) {
			getUiDevice().wakeUp();
		}
	}
	/**
	 * from relative size
	 * @param normalizedX
	 * @return
	 */
	//test ok
	public int toScreenX(float normalizedX) {
		Float f1 = (normalizedX * Integer.valueOf(getUiDevice()
				.getDisplayWidth()));
		return f1.intValue();
	}
	//test ok
	public int toScreenY(float normalizedY) {
		Float f1 = normalizedY
				* Integer.valueOf(getUiDevice().getDisplayHeight());
		return f1.intValue();
	}
	
	/**
	 * Press Key of Home, back, delete, menu, down, up, left, right, center, search, recentapp 
	 * power, volumeup, volumedown, mute, camera, etc.
	 * @param Key
	 */
	//test ok
	public void pressKey(String Key) {
		if (Key.equalsIgnoreCase("Home")) {
			getUiDevice().pressHome();

		} else if (Key.equalsIgnoreCase("back")) {
			getUiDevice().pressBack();
		} else if (Key.equalsIgnoreCase("delete")) {
			getUiDevice().pressDelete();
		} else if (Key.equalsIgnoreCase("enter")) {
			getUiDevice().pressEnter();
		} else if (Key.equalsIgnoreCase("menu")) {
			getUiDevice().pressMenu();
		} else if (Key.equalsIgnoreCase("down")) {
			getUiDevice().pressDPadDown();
		} else if (Key.equalsIgnoreCase("up")) {
			getUiDevice().pressDPadUp();
		} else if (Key.equalsIgnoreCase("left")) {
			getUiDevice().pressDPadLeft();
		} else if (Key.equalsIgnoreCase("right")) {
			getUiDevice().pressDPadRight();
		} else if (Key.equalsIgnoreCase("center")) {
			getUiDevice().pressDPadCenter();
		} else if (Key.equalsIgnoreCase("search")) {
			getUiDevice().pressSearch();
		} else if (Key.equalsIgnoreCase("recentapp")) {
			try {
				getUiDevice().pressRecentApps();
			} catch (RemoteException e) {

			}
		} else if(Key.equalsIgnoreCase("power")) {
			pressKeyCode(KeyEvent.KEYCODE_POWER);
		} else if(Key.equalsIgnoreCase("volumeup")) {
			pressKeyCode(KeyEvent.KEYCODE_VOLUME_UP);
		} else if(Key.equalsIgnoreCase("volumedown")) {
			pressKeyCode(KeyEvent.KEYCODE_VOLUME_DOWN);
		}  else if(Key.equalsIgnoreCase("mute")) {
			pressKeyCode(KeyEvent.KEYCODE_VOLUME_MUTE);
		} else if(Key.equalsIgnoreCase("camera")) {
			pressKeyCode(KeyEvent.KEYCODE_CAMERA);
		}
		else {		
			return;
		}
	}// end of pressKey

	/**
	 * click coordinate
	 * @param x
	 * @param y
	 */
	//test ok
	public void clickPoint(int x, int y) {
		getUiDevice().click(x, y);
	}
	
	
	/**
	 *  Click relative point on the screen, such as clickPointByRelative(0.5f, 0.5f), it's on the center of the screen.
	 *  you can get x/width, y/height to get the value
	 * @param x
	 * @param y
	 */
	public void clickPointByRelative( float x, float y){
		clickPoint(toScreenX(x), toScreenY(y));
	}
	
	
	/**
	 * click coordinate
	 * @param pt Point of target you click
	 */
	public void clickPoint(Point pt) {
		getUiDevice().click(pt.x, pt.y);
	}

	
	/**
	 * Open launcher and find application by app name
	 * @param text app name appears in launcher
	 * @return
	 * @throws UiObjectNotFoundException
	 */
	//test failed on new Home, new Home is customized View, can't get anything there.
	//test ok on old Home, like Hayabusa JB
	public boolean openLauncherAndFind(String text)
			throws UiObjectNotFoundException {
		pressKey("Home");
		UiObject allAppsButton = new UiObject(
				new UiSelector().description("Applications"));
		allAppsButton.clickAndWaitForNewWindow();
		UiScrollable apps = new UiScrollable(new UiSelector().scrollable(true));

		// .className("android.widget.AdapterView"));
		apps.setAsVerticalList();
		UiObject target = apps.getChildByText(
				new UiSelector().className("android.widget.TextView"), text);
		target.click();
		return true;
	}

	/**
	 * Launch Application by package name and class name
	 *
	 * @param pkg
	 *            package name, like "com.android.calculator2"
	 * @param cls
	 *            cls name of the launchable Activity of the package, like
	 *            ".Calculator"
	 */
	// test ok
	public void launchApp(String pkg, String cls) {
		String prog = "am start -n " + pkg + "/" + cls;
		try {
			Process process = Runtime.getRuntime().exec(prog);
			process.waitFor();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
	}

	/**
	 * Long click view cls is "text"
	 *
	 */
	//test ok
	public void longClickText(String text) throws UiObjectNotFoundException {
		//UiObject uiobj = new UiObject(new UiSelector().text(text));
		longTap(getCoordinateByText(text).x, getCoordinateByText(text).y, 3000);
	}
	//test ok
	public void longClickContentDesc(String text)
			throws UiObjectNotFoundException {
		longTap(getCoordinateByDes(text).x, getCoordinateByDes(text).y, 3000);
	}

	/**
	 * Long click view cls contains "text"
	 *
	 */
	//test ok
	public void longClickTextContains(String text)
			throws UiObjectNotFoundException {
		UiObject uiobj = new UiObject(new UiSelector().textContains(text));
		longTap(uiobj.getBounds().centerX(), uiobj.getBounds().centerY(), 3000);
	}
	/**
	 * Navigation up (in action bar) standard android behavior
	 * @throws UiObjectNotFoundException
	 */
	public void navigationUp() throws UiObjectNotFoundException{
		UiObject uiobj = new UiObject(new UiSelector().description("Navigate up"));
		uiobj.clickAndWaitForNewWindow();
	}
	/**
	 * Click More options menu, standard android behavior
	 * @throws UiObjectNotFoundException
	 */
	public void moreMenu() throws UiObjectNotFoundException{
		UiObject uiobj = new UiObject(new UiSelector().description("More options"));
		uiobj.clickAndWaitForNewWindow();
	}

	/**
	 * press key code test Yuga OK
	 */
	//test ok
	public void pressKeyCode(int key) {
		getUiDevice().pressKeyCode(key);
	}

	/**
	 * Open status bar test on Yuga
	 */
	public void openStatusBar() {
		int w = getUiDevice().getDisplayWidth();
		int h = getUiDevice().getDisplayHeight();
		getUiDevice().swipe(w / 2, 30, w / 2, h, 30);
	}
	/**
	 * Open Application from Recent Apps window by press recent virtual key
	 * @param appName
	 * @throws UiObjectNotFoundException
	 */
	// test ok
	public void openAppFromRecentApps(String appName) throws UiObjectNotFoundException{
		pressKey("recentapp");		
		Point pt = getCoordinateByText(appName);
		if (getUiDevice().getDisplayRotation() == 0) {
			clickPoint(pt.x + toScreenX(0.2f), pt.y + toScreenY(0.15f));
		} else {
			clickPoint(pt.x, pt.y-toScreenY(0.2f));
		}
	}

	/**
	 * click icon by row and column on launcher, you can use it when
	 * can not get anything on screen*
	 * @param col
	 *            X;
	 * @param row
	 *            Y;
	 * @param page
	 * 			  scroll page number;
	 */
	public void clickLauncher(int col, int row, int page) {
		// if (getUiDevice().getProductName().equalsIgnoreCase("C")) {
		// for on screen
		col = col - 1;
		row = row - 1;
		sleep(1500);
		clickPointByRelative(0.493f, 0.95f);// press Launcher

		for (int i = 0; i < page - 1; i++) {
			sleep(1000);
			scroll("left");
		}
		sleep(1200);
		int startX = toScreenX(0.0277f);
		int startY = toScreenY(0.0911f);
		int W = getUiDevice().getDisplayWidth() - toScreenX(0.0277f) * 2;
		int H = getUiDevice().getDisplayHeight() - toScreenY(0.0911f)
				- toScreenY(0.131f);
		Float x = startX + col * W / 4 + (float) W / 8;
		Float y = startY + row * H / 5 + (float) W / 10;
		// Log.e(AUTOTEST_TAG, "XXXXX: " + Float.toString(x));
		// Log.e(AUTOTEST_TAG, "YYYYY: " + Float.toString(y));
		getUiDevice().click(x.intValue(), y.intValue());
	}

	/**
	 * Drag screen to what orientation, orientation can be "left", "right",
	 * "up", "down" such as "left" is from right of screen to left of screen
	 *
	 * @param orientation
	 *            orientation can be "left", "right", "up", "down"
	 *
	 *
	 */
	//test ok
	public void scroll(String orientation) {
		int W = getUiDevice().getDisplayWidth();
		int H = getUiDevice().getDisplayHeight();
		if (orientation.equalsIgnoreCase("left")) {
			drag(3 * W / 4, H / 2, W / 4, H / 2, 20);
		} else if (orientation.equalsIgnoreCase("right")) {
			drag(W / 4, H / 2, 3 * W / 4, H / 2, 20);
		} else if (orientation.equalsIgnoreCase("up")) {
			drag(W / 2, 3 * H / 4, W / 2, H / 4, 50);
		} else if (orientation.equalsIgnoreCase("down")) {
			drag(W / 2, H / 4, W / 2, 3*W / 4, 50);
		} else {
			drag(3 * W / 4, H / 2, W / 4, H / 2, 20);
		}
	}



	/**
	 * set current setOrientationLandscape()
	 *
	 */
	//test ok
	public void setOrientationLandscape() throws RemoteException {
		if (getUiDevice().getDisplayRotation() == 0) {
			getUiDevice().setOrientationLeft();
			sleep(1000);
		}
		getUiDevice().unfreezeRotation();
	}

	/**
	 * set current setOrientationPortrait()
	 *
	 */
	//autorotate enabled can't work
	public void setOrientationPortrait() throws RemoteException {
		int oriet = getUiDevice().getDisplayRotation();
		if (oriet == 1 || oriet == 3) {
			getUiDevice().setOrientationNatural();
		}
		getUiDevice().unfreezeRotation();
	}

	/**
	 * enter Text in Editor
	 *
	 * @param text
	 *            Text you want to enter
	 * @param cls
	 *            Text editor on the screen, please use uiautomatorviewer to
	 *            find it often as "android.widget.EditText" or
	 *            "android.widget.MultiAutoCompleteTextView"
	 *            "android.widget.ExtractEditText",
	 *            "android.widget.AutoCompleteTextView"
	 * @param instance
	 *           	number of instance, begin from 0
	 * @throws UiObjectNotFoundException
	 *
	 *             //enterTextInEditor("ABCDEFGHIJK, abcde;zgdidsgds76204781?",
	 *             "android.widget.EditText", 1); //enterTextInEditor("123567",
	 *             "android.widget.MultiAutoCompleteTextView", 1);
	 *             user pressKey("back") after the lines, because IME will mask half of the screen.
	 */
	// test ok
	public void enterTextInEditor(String text, String cls, int instance)// test ok
			throws UiObjectNotFoundException {
		UiObject obj = new UiObject(new UiSelector().className(cls)
				.instance(instance));
		obj.setText(text);
		//obj.click();
		//pressKey("back");
	}
	
	public void enterText(String text){
		Instrumentation inst = new Instrumentation();
		inst.sendStringSync(text);
	}



	/**
	 * fling to Beginning on scrollable object
	 * @param cls Class name of scrollable object, most in "android.widget.ListView" 
	 * @throws UiObjectNotFoundException
	 */
	//test ok
	public void flingToBegining(String cls) throws UiObjectNotFoundException {
		UiScrollable scroll = new UiScrollable(new UiSelector().className(cls));
		if (scroll.isScrollable()) {
			scroll.flingToBeginning(10);
		}
	}

	/**
	 * scroll to beginning with scrolls
	 *
	 * @param direction
	 *            scroll direction as "Vertical" or "Horizontal", defaut is
	 *            Horizontal
	 * @param maxScrolls max try times
	 */
	//test ok
	public void scrollToBegining(String direction, int maxScrolls) {
		if (direction.contains("Vertical")) {
			for (int i = 0; i < maxScrolls; i++) {
				dragDirection("down", 20);
			}
		} else {
			for (int i = 0; i < maxScrolls; i++) {
				dragDirection("right", 20);
			}
		}
	}
	/**
	 * Fling to end, only works on scrollable views
	 * @param cls	class name of scrollable, most in "android.widget.ListView" 
	 * @throws UiObjectNotFoundException
	 */
	//test ok
	public void flingToEnd(String cls) throws UiObjectNotFoundException {
		UiScrollable scroll = new UiScrollable(new UiSelector().className(cls));
		scroll.flingToEnd(10);
	}
	/**
	 * Scroll up in scrollable View, most in "android.widget.ListView" 
	 * @param cls scrollable class Name, most in "android.widget.ListView" 
	 * @param steps
	 * @throws UiObjectNotFoundException
	 */
	//test ok
	public void scrollUpOnView(String cls, int steps)
			throws UiObjectNotFoundException {
		UiScrollable scroll = new UiScrollable(new UiSelector().className(cls));
		scroll.swipeUp(steps);

	}

	/**
	 * get Child UI Ojbect in ScrollView test failed, fail rate 50%
	 *
	 * @param scrollCls
	 *            scrollable class name
	 * @param text
	 *            the text you need
	 *
	 * @return UiObject UI Object you can operator
	 * @throws UiObjectNotFoundException
	 * <pre> getChildObjInScrollView("android.widget.ListView", "About phone", 5).clickAndWaitForNewWindow();
	 * </pre>
	 */
	// test failed, fail rate 50%
	public UiObject getChildObjInScrollView(String scrollCls, String text,
			int maxScrolls) throws UiObjectNotFoundException {

		UiScrollable scroll = new UiScrollable(
				new UiSelector().className(scrollCls));
		scroll.setMaxSearchSwipes(maxScrolls);
		scroll.flingToBeginning(maxScrolls);
		for (int i = 0; i < maxScrolls; i++) {
			UiObject child = new UiObject(new UiSelector().text(text));
			if (child.exists()) {
				break;
			}
			scroll.scrollForward();
		}
		return (new UiObject(new UiSelector().text(text)));
	}

	/**
	 * Scroll and find a text on scrollable object(get scrollable=true by
	 * uiautomatorviewer(monitor)
	 *
	 * @param text
	 *            text you want to find
	 * @param direction
	 *            the direction is scroll direction, value should be
	 *            "Horizontal" or "Vertical"
	 * @param maxScrolls
	 *            the value max tries.
	 * @return UiObject return UiObject you can operate
	 * @throws UiObjectNotFoundException
	 *
	 * @see getChildObjInScrollView similar method, but this method don't need
	 *      to detect scrollable view
	 */
	// test ok
	public UiObject scrollToFindText(String text, String direction,
			int maxScrolls) throws UiObjectNotFoundException {
		UiScrollable scroll = new UiScrollable(
				new UiSelector().className("android.widget.ListView"));
		if (scroll.exists()) {
			if (scroll.isScrollable()) {
				if (direction.equalsIgnoreCase("Horizontal")) {
					scroll.setAsHorizontalList();
				} else {
					scroll.setAsVerticalList();
				}
				scroll.setMaxSearchSwipes(maxScrolls);
				scroll.flingToBeginning(maxScrolls);
				for (int i = 0; i < maxScrolls; i++) {
					UiObject child = new UiObject(new UiSelector().text(text));
					if (child.exists()) {
						break;
					}
					scroll.scrollForward();
				}
			}
		} else {

			if (direction.equalsIgnoreCase("Horizontal")) {
				scrollToBegining("Horizontal", 6);
				for (int i = 0; i < maxScrolls; i++) {
					UiObject child = new UiObject(new UiSelector().text(text));
					if (child.exists()) {
						break;
					}
					dragDirection("left", 20);
				}
			} else if (direction.equalsIgnoreCase("Vertical")) {
				scrollToBegining("Vertical", 6);
				for (int i = 0; i < maxScrolls; i++) {
					UiObject child = new UiObject(new UiSelector().text(text));
					if (child.exists()) {
						break;
					}
					dragDirection("up", 20);
				}
			}

		}

		return (new UiObject(new UiSelector().text(text)));
	}
	/**
	 * Find view by class name and instance, return UiObject can be operatable or verfication
	 * @param clsName
	 * @param instance
	 * @return UiObject you can operate the UiObject like click or other operations
	 */
	//test ok
	public UiObject findView(String clsName, int instance) {
		UiObject obj = new UiObject(new UiSelector().className(clsName).instance(instance));
		return obj;
	}

	/**
	 * find Text and return UiObject, then you can operate this UiObject
	 *
	 * @param text
	 * @return UiOject You can operate with this object
	 * 		   example: assertTrue("Click About Phone failed", findText("Apps").exists())
	 *         findText("About phone").clickAndWaitForNewWindow());
	 */
	// test ok
	public UiObject findText(String text) {
		UiObject obj = new UiObject(new UiSelector().text(text));
		return obj;
	}

	/**
	 *
	 * @param storePath
	 * @return
	 */
	// test ok
	// storePath=Uiscreenshot
	// will in /sdcard/Uiscreenshot/com.android.settings20130602_093451.png
	public boolean takeScreenshot(String storePath) {
		Log.v(AUTOTEST_TAG, "takeScreenshot.... ");
		// if(Environment.getExternalStorageState() ==
		// Environment.MEDIA_MOUNTED){
		Log.v(AUTOTEST_TAG, "MEDIA_MOUNTED.... ");
		//String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
		String baseDir = "/sdcard";
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
		String currentDateandTime = sdf.format(new Date());
		String fileName = getUiDevice().getCurrentPackageName()
				+ currentDateandTime.toString() + ".png";

		File f = new File(baseDir + File.separator +storePath 
				+ File.separator + fileName);
		Log.v(AUTOTEST_TAG, "filename: " + fileName);
		Log.v(AUTOTEST_TAG, "firdir: " + f.getAbsolutePath());
		System.out.println(f.getAbsolutePath());
		try {

			if (!f.getParentFile().exists()) {
				 Runtime.getRuntime().exec("mkdir "+
				  f.getParentFile().getAbsolutePath()).waitFor();
			}
			//Process process = Runtime.getRuntime().exec("screencap " + fileName);
			//process.waitFor();
			getUiDevice().takeScreenshot(f, 0.5f, 30);

		} catch (IOException e) {
			// TODO Auto-generated catch block
			Log.v(AUTOTEST_TAG, "filename1: " + fileName);
			Log.v(AUTOTEST_TAG, "filename1: " + fileName);
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			Log.v(AUTOTEST_TAG, "filename: " + fileName);
			Log.v(AUTOTEST_TAG, "filename: " + fileName);
			e.printStackTrace();
		}
		// }
		// return getUiDevice().takeScreenshot(f, scale, quality);
		return true;
	}

	// ////////////////////////////////////
	/**
	 * assert string is presenting on screen.
	 *
	 * @param string
	 *            The screen to verify
	 *
	 */
	public void assertTextPresent(String string) {// test ok
		assertTrue("Text \"" + string + "\" is not existing", findText(string)
				.exists());
	}

	/**
	 * Assert class name is present on screen
	 *
	 * @param cls
	 *            class name
	 */
	public void assertViewMatches(String cls) { // test ok
		UiObject obj = new UiObject(new UiSelector().className(cls));
		assertTrue("Class View: \"" + cls + "\" is not existing", obj.exists());
	}

	/**
	 * assert by current package name
	 *
	 * @param pkgName
	 *            package is appear or not
	 */
	public void assertPackageAppear(String pkgName) {
		assertEquals(
				"Package name: \"" + pkgName + "\" is not current package",
				pkgName, getUiDevice().getCurrentPackageName());

	}

	/**
	 * Get Coordinate by Text, the Coordinate is center of the text bounds
	 *
	 * @param text
	 *            The text you want to find
	 * @return Point Center of the text
	 * @throws UiObjectNotFoundException
	 */
	// test ok clickPoint(getCoordinateByText("About phone"));
	public Point getCoordinateByText(String text)
			throws UiObjectNotFoundException {
		Rect rect = findText(text).getBounds();
		Point pt = new Point(rect.centerX(), rect.centerY());
		return pt;
	}
	
	public Point getCoordinateByDes(String text)
			throws UiObjectNotFoundException {
		UiObject obj= new UiObject(new UiSelector().descriptionContains(text));
		Rect rect = obj.getBounds();//findText(text).getBounds();
		Point pt = new Point(rect.centerX(), rect.centerY());
		return pt;
	}
	

	/**
	 * get coordinate of child item in complex view
	 *
	 * @param parentCls
	 *            parent class name
	 * @param parentInstance
	 *            
	 * @param targetCls
	 *            target class name you want to get
	 * @param targetInstance
	 *            target class instance you want to get
	 * @return Point of the target class coordinate
	 * @throws UiObjectNotFoundException
	 */
	public Point getCoordinateFromChildView(String parentCls, int parentInstance,
			String targetCls, int targetInstance) throws UiObjectNotFoundException {
		//UiCollection uiCol = new UiCollection()
		UiObject obj = new UiObject(new UiSelector().className(parentCls)
				.instance(parentInstance).className(targetCls).instance(targetInstance));
		Point pt = new Point(obj.getBounds().centerX(), obj.getBounds()
				.centerY());
		return pt;
	}
	/**
	 * Get number of className in parent class name(parentCls and it's instance on the screen).
	 * @param parentCls  Parent class name
	 * @param instanceParent instance of the parent class on the screen
	 * @param className The class name you want to get.
	 * @return
	 */
	public int getItemsNumber(String parentCls, int instanceParent, String className ){
		UiCollection uiCol = new UiCollection(new UiSelector().className(parentCls).instance(instanceParent));
		return uiCol.getChildCount(new UiSelector().className(className));			
	}
	/**
	 * check if the view contains the text by regular expression
	 * @param regexp text regular expression
	 * @return
	 */
	//test ok
	public boolean isViewWithTextContainsRegExp(String regexp) {
		UiObject obj = new UiObject(new UiSelector().textMatches(regexp));
		return obj.exists();
	}
	/**
	 * Reads the UI element's package property of specific class name
	 * @param cls class name of the view
	 * @param instance Instance is from 0, the first is 0, if you find TextView is 3rd, you should set 2
	 * @return
	 * @throws UiObjectNotFoundException
	 */
	public String getTextOnView(String cls, int instance) throws UiObjectNotFoundException{
		UiObject obj = new UiObject(new UiSelector().className(cls).instance(instance));
		return obj.getText();
	}
	/**
	 * check if the view contains the text, if true the text presents on the screen
	 * @param text
	 * @return true if text presents on screen, else not
	 */
	//test ok
	public boolean isViewWithTextContains(String text) {
		UiObject obj = new UiObject(new UiSelector().textContains(text));
		return obj.exists();
	}

	/**
	 * if UI leave your application, the method will press Back key try to get
	 * back.
	 *
	 * @param targetPkg
	 *            your target package name
	 */
	public void dismissUnWantedWindow(final String targetPkg) {
		UiWatcher dismissWatcher = new UiWatcher() {
			@Override
			public boolean checkForCondition() {
				for (int i = 0; i < 2; i++) {
					if (!getUiDevice().getCurrentPackageName()
							.equalsIgnoreCase(targetPkg)) {
						pressKey("Back");
					}
				}
				return getUiDevice().getCurrentPackageName().equalsIgnoreCase(
						targetPkg);
			}
		};
		UiDevice.getInstance()
				.registerWatcher("dismissWatcher", dismissWatcher);
		UiDevice.getInstance().runWatchers();
	}

	/**
	 * Fail the test
	 *
	 * @param msg
	 */
	public void failTest(String msg) {
		Assert.fail(msg);
	}



	/**
	 * Wait for text exists with timeout(in ms)
	 * @param str text you want to wait
	 * @param time timeout in ms
	 * @return
	 */
	//test ok
	public boolean waitForTextExists(String text, int timeout){
	    UiObject obj = new UiObject(new UiSelector().text(text));
	    return obj.waitForExists(timeout);
	}
	/**
	 * Wait for text gone from the screen with timeout
	 * @param text
	 * @param timeout
	 * @return
	 */
	//test ok
	public boolean waitForTextGone(String text, int timeout){
        UiObject obj = new UiObject(new UiSelector().text(text));
        return obj.waitUntilGone(timeout);
    }
	
	public void longTap(int x, int y, int time){
		long downTime = SystemClock.uptimeMillis();
	    long eventTime = SystemClock.uptimeMillis();
	    MotionEvent event = MotionEvent.obtain(downTime, eventTime, 0, x, y, 0);
	    //getUiDevice().longTap(x, y);
		Instrumentation inst = new Instrumentation();
		try {
			inst.sendPointerSync(event);
		} catch (SecurityException e) {
			Assert.assertTrue(
					"Click can not be completed! Something is in the way e.g. the keyboard.",
					false);
		}
		 eventTime = SystemClock.uptimeMillis();
		 event = MotionEvent.obtain(downTime, eventTime, 2, x + 1.0F, y + 1.0F, 0);
		 inst.sendPointerSync(event);
		 if (time > 0){
			 sleep(time);
		 } else {
			 sleep((int)((ViewConfiguration.getLongPressTimeout() * 2.5F)));
		 }
		 eventTime = SystemClock.uptimeMillis();
		 event = MotionEvent.obtain(downTime, eventTime, 1, x, y, 0);
		 inst.sendPointerSync(event);
		 sleep(500);		 
	}
	/**
	 * Check the CheckBox is checked or not, 
	 * @param instance instance number on the screen, start from 0
	 * @return boolean True means  checked, false means not checked.
	 * @throws UiObjectNotFoundException
	 */
	//test ok
	public boolean isCheckedOfCheckBox(int instance) throws UiObjectNotFoundException{
		UiCollection uiC = new UiCollection(new UiSelector());
		UiObject obj = uiC.getChildByInstance(new UiSelector().className("android.widget.CheckBox"), instance);
		return obj.isChecked();		
	}
	/**
	 * Check the Switch is checked or not, 
	 * @param instance instance number on the screen, start from 0
	 * @return boolean True means  checked, false means not checked.
	 * @throws UiObjectNotFoundException
	 */
	//test ok
	public boolean isCheckedOfSwitch(int instance) throws UiObjectNotFoundException{
		UiCollection uiC = new UiCollection(new UiSelector());
		UiObject obj = uiC.getChildByInstance(new UiSelector().className("android.widget.Switch"), instance);
		return obj.isChecked();		
		
	}
	
	/**
     * Check the CheckedTextView is checked or not,
     * @param instance instance number on the screen, start from 0
     * @return boolean True means  checked, false means not checked.
     * @throws UiObjectNotFoundException
     */
	   //test ok
    public boolean isCheckedOfCheckBoxTextView(int instance) throws UiObjectNotFoundException{
        UiCollection uiC = new UiCollection(new UiSelector());
        UiObject obj = uiC.getChildByInstance(new UiSelector().className("android.widget.CheckedTextView"), instance);
        return obj.isChecked();
    }

	/**
	 * inject long key event
	 * @param keycode
	 * @param sleepTime
	 * @throws Exception
	 */
	public void injectLongKeyEvent(int keycode, int sleepTime) throws Exception {		
		KeyEvent kd= new KeyEvent( KeyEvent.ACTION_DOWN, keycode);
		inst.sendKeySync(kd);
		if( sleepTime < ViewConfiguration.getLongPressTimeout()) {
			sleep(ViewConfiguration.getLongPressTimeout() * 2 +100);
		} else {
			sleep(sleepTime);
		}
		KeyEvent kup= new KeyEvent( KeyEvent.ACTION_DOWN, keycode);
		inst.sendKeySync(kup);		   
	  }
	 //test ok, but not so good
	/**
	 * clear 
	 * @param instance the text edit in the screen..
	 * @param num Max Number of text you want to clear
	 * @throws UiObjectNotFoundException
	 */
	public void clearEditText(int instance, int num) throws UiObjectNotFoundException{
		UiObject obj = new UiObject(new UiSelector().className("android.widget.EditText").instance(instance));
		if(obj.getText().isEmpty())
			return;
		obj.clickBottomRight();		
		
		try {
			Instrumentation inst = new Instrumentation();
			for (int i = 0; i < num; i++) {
				inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DEL); // pressKeyCode(KeyEvent.KEYCODE_DEL);
			}
		} catch (Exception e) {

		}

	}

}
